const UTIL = require('./util')
const CONSTANT = require('./constant')
const issues = require('./issues')

/**
 * search class
 * {
 *    project_name
 *    project_url
 *    issue_id
 *    issue_url
 *    title
 *    description // 支持MD
 *    state
 *    labels
 *    author
 *    created_ts
 * }
 */
module.exports = class Search {
  constructor(searchStr, page, perPage) {
    this.page = page
    this.perPage = perPage
    this.searchStr = searchStr
  }

  /**
   * assemble all search type
   *
   * @return 聚合之后的issue链接和摘要
   *         {
   *           id: String,
   *           iid: String,
   *           name: String, // project name
   *           title: String,
   *           link: String
   *         }
   */
  assemble() {
    return Promise.all([this.issues(), this.notes()]).then(data => {
      // TODO: 处理issues和notes
      // 使用data包一层是为了和单独查询issue和note返回的格式一样，方便上层处理
      // return ([...data[0], ...data[1]]).slice(0, this.perPage)
      return [...data[0], ...data[1]]
    })
  }

  /**
   * search issues
   * @return 请求回来的issues
   */
  issues() {
    return UTIL.request(UTIL.buildSearchUrl('project', 'issue', this.searchStr, this.page, this.perPage)).then(({ data: issues }) => {
      return issues.map(issue => {
        const { title, description, state, labels, author, web_url, iid, created_at, project_id } = issue
        return {
          project_name: 'CCSBC/carcloud',
          title,
          state,
          labels,
          author,
          issue_url: web_url,
          project_url: `${CONSTANT.HOST}/${project_id}`,
          issue_id: iid,
          description: description || title,
          created_ts: created_at,
          type: 'issue'
        }
      })
    }).catch(err => {
      // handle err
      throw new Error(`查询 issue 失败: ${err}; Error.response: ${err && err.response && JSON.stringify(err.response.data)}. Search string: ${this.searchStr}`)
    })
  }

  /**
   * search notes
   * notes == comments
   *
   * @return 请求回来的notes
   */
  notes() {
    /**
     * {
     *    project_name
     *    project_url
     *    issue_id
     *    issue_url
     *    title
     *    description // 支持MD
     *    state
     *    labels
     *    author
     *    created_ts
     * }
     */
    const rets = []
    return UTIL.request(UTIL.buildSearchUrl('project', 'note', this.searchStr, this.page, this.perPage)).then(resp => {
      const { data: notes } = resp
      return notes.map(item => {
        const { noteable_type, noteable_iid, body, created_at } = item
        if (noteable_type.trim().toLowerCase() === 'issue') {
          // 保证是issue中的note
          rets.push({
            issue_id: noteable_iid,
            description: body,
            created_ts: created_at,
            type: 'note'
          })
          return noteable_iid
        }
        return false
      })
    }).then(iids =>
      iids.filter(iid => !!iid)
    ).then(iids =>
      iids.map(iid => {
        return issues.getIssueByIid(iid)
      })
    ).then(pse => {
      return Promise.all(pse).then(issues => {
        issues.forEach(({ data: issue }, index) => {
          const { title, state, labels, author, project_id, web_url } = issue
          rets[index] = Object.assign(rets[index], {
            project_name: 'CCSBC/carcloud',
            title,
            state,
            labels,
            author,
            issue_url: web_url,
            project_url: `${CONSTANT.HOST}/${project_id}`
          })
        })
        return rets
      })
    }).catch(err => {
      // handle err
      throw new Error(`查询 note 失败: ${err}; Error.response: ${err && err.response && JSON.stringify(err.response.data)}. Search string: ${this.searchStr}`)
    })
  }
}
